package com.comunity_cloud.client.model;

import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.Vector;

import javax.swing.table.AbstractTableModel;

import com.comunity_cloud.client.model.CommunityFile.Chunk;
import com.comunity_cloud.client.model.CommunityFile.State;
import com.user_hosted_storage.dto.CommunityDTO;


public class CommunityModel2 extends AbstractTableModel implements CommunityModelInterface{

	/**
	 * 
	 */
	private static final long serialVersionUID = -7437180590674731212L;

	private List<CommunityFile> rows = new Vector<>();
	private CommunityDTO communityDTO;

	public CommunityModel2(CommunityDTO communityDTO) {
		this.communityDTO = communityDTO;
		MainModel2.getInstance().getFileListClient().addCommunityFilesListener(communityDTO.getId(), this);
		MainModel2.getInstance().getUploadFilesManager().addLocalFilesListener(communityDTO.getId(), this);
	}

	@Override
	public int getRowCount() {
		return rows.size();
	}

	@Override
	public int getColumnCount() {
		return 3;
	}

	@Override
	public String getColumnName(int column) {
		String name = "??";
		switch (column) {
		case 0:
			name = "File";
			break;
		case 1:
			name = "Size";
			break;
		case 2:
			name = "Status";
			break;
		}
		return name;
	}

	@Override
	public Object getValueAt(int rowIndex, int columnIndex) {
		CommunityFile rowData = rows.get(rowIndex);
		Object value = null;
		switch (columnIndex) {
		case 0:
			value = rowData.getPath();
			break;
		case 1:
			value = rowData.getLength() / 1024 + " KB";
			break;
		case 2:
			value = rowData.getProgress();
			break;
		}
		return value;
	}


	public void addFile(CommunityFile file) {

		if(rows.contains(file)){
			int index = rows.indexOf(file);
			CommunityFile row = rows.get(index);
			Set<Entry<Long, Chunk>> chunks = file.getChunks();
			Map<Long, Chunk> currentChunks = row.getChunksMap();
			for (Entry<Long, Chunk> entry : chunks) {
				Chunk currentChunk = currentChunks.get(entry.getKey());
				if(currentChunk == null) {
					currentChunks.put(entry.getKey(), entry.getValue());
				} else {
					if(entry.getValue().primaryHost != null) {
						currentChunk.primaryHost = entry.getValue().primaryHost; 
					}
					if(entry.getValue().redundantHost != null) {
						currentChunk.redundantHost = entry.getValue().redundantHost; 
					}
				}
				
			}
			row.setLength(file.getLength());
			fireTableRowsUpdated(index, index);
			return;
		}
		
		rows.add(file);
		fireTableRowsInserted(rows.size() - 1, rows.size() - 1);
		MainModel2.getInstance().getUploadFilesManager().addFileStatusListener(file, this);
	}

	protected void updateStatus(CommunityFile rowData) {

		if (rowData != null) {
			int row = rows.indexOf(rowData);
			fireTableCellUpdated(row, 3);
		}
	}

	@Override
	public void newCommunityFileAdded(CommunityFile communityFile) {
		addFile(communityFile);
	}

	@Override
	public void fileAdded(CommunityFile file) {
		addFile(file);
	}

	@Override
	public void statusChanged(CommunityFile file, State state) {
		int index = rows.indexOf(file);
		rows.get(index).setState(state);
		fireTableRowsUpdated(index,index);
	}

	@Override
	public void onProgressChange(CommunityFile file, int progress) {
		file.setProgress(progress);
		int index = rows.indexOf(file);
		fireTableRowsUpdated(index,index);
	}
	
	public CommunityFile getRow(int rowIndex) {
		return rows.get(rowIndex);
	}

	public CommunityFile removeRow(int rowIndex) {
		CommunityFile file = rows.remove(rowIndex);
		fireTableRowsDeleted(rowIndex, rowIndex);
		return file;
	}

	@Override
	public void communityFileDeleted(CommunityFile communityFile) {
		rows.remove(communityFile);
		fireTableDataChanged();
	}

	@Override
	public CommunityDTO getCommunity() {
		return communityDTO;
	}
}

